﻿using DevExpress.Data.Utils;
using DevExpress.XtraPrinting.Native.Lines;
using HalconDotNet;
using ImageDefine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ImageTool2DCal
{
   
    public class ImageActioner2DCal
    {
        public ImageTool2DCal imageTool;

        public ImageActioner2DCal()
        {

        }
        public ImageActioner2DCal(ImageTool2DCal toolBase)
        {
            imageTool = toolBase;

        }

        public bool Run(HalconDotNet.HImage imageInput, SmartDisplayControl.SmartDisplayControl disPlayControl)
        {
            bool bResult = false;
            GeneralLib.HiPerfTimer timer = new GeneralLib.HiPerfTimer();
            timer.Start();

            try
            {
                imageTool.ImageToolResults = new List<ImageToolResult>();
                imageTool.OutPutResults.Clear();
                if (imageTool.strFormName == ""|| imageTool.strToName == "")
                {
                    bResult = false;
                    imageTool.bResultOK = false;
                }
                else
                {
                    try
                    {

                        ImageToolBase toolFrom = imageTool.imageTask.dicTools[imageTool.strFormName];
                        ImageToolBase toolTo = imageTool.imageTask.dicTools[imageTool.strToName];
                        if ((toolFrom.ImageToolResults.Count == toolTo.ImageToolResults.Count) && toolFrom.ImageToolResults.Count > 0)
                        {
                            for (int i = 0; i < toolFrom.ImageToolResults.Count; i++)
                            {
                                RunToool(imageInput, disPlayControl, i, toolFrom, toolTo);
                            }
                            ImageResultLine imageResultCircle = imageTool.ImageToolResults[0] as ImageResultLine;
                            imageTool.ResultX = imageResultCircle.ResultX;
                            imageTool.ResultY = imageResultCircle.ResultY;
                            imageTool.dResultRow1 = imageResultCircle.LineStartY;
                            imageTool.dResultCol1 = imageResultCircle.LineStartX;
                            imageTool.dResultRow2 = imageResultCircle.LineEndY;
                            imageTool.dResultCol2 = imageResultCircle.LineEndX;
                            imageTool.bResultOK = imageResultCircle.Result;
                        }
                        else
                        {
                            bResult = false;
                            imageTool.bResultOK = false;
                        }
                        
                    }
                    catch
                    {

                    }
                }
            }
            catch//(Exception ex)
            {
                bResult = false;
                imageTool.bResultOK = false;
            }

            imageTool.dTimeUsed = timer.Duration;
            return bResult;
        }
        public bool RunToool(HImage image, SmartDisplayControl.SmartDisplayControl disWnd, int iIndex, ImageToolBase toolFrom,ImageToolBase toolTo)
        {

            imageTool.ResultX = 0.0;
            imageTool.ResultY = 0.0;
            imageTool.ResultA = 0.0;
            imageTool.ResultOK = false;
            imageTool.dResultScore = 0.0;


            if (imageTool.Setting.CalMode == CalMode.PointToPoint)
            {
                RunPointToPoint(image, disWnd, iIndex, toolFrom, toolTo);
            }
            if (imageTool.Setting.CalMode == CalMode.PointToLine)
            {
                RunPointToLine(image, disWnd, iIndex, toolFrom, toolTo);
            }
            if (imageTool.Setting.CalMode == CalMode.LineToLine)
            {
                RunLineToLine(image, disWnd, iIndex, toolFrom, toolTo);
            }
            if (imageTool.Setting.CalMode == CalMode.CircleToLine)
            {
                RunCircleToLine(image, disWnd, iIndex, toolFrom, toolTo);
            }
            #region 结果赋值

            #endregion

            return true;

        }
        public void RunPointToPoint(HImage image, SmartDisplayControl.SmartDisplayControl disWnd, int iIndex, ImageToolBase toolFrom, ImageToolBase toolTo)
        {
            IPoint pointFrom= toolFrom as IPoint;
            IPoint pointTo = toolTo as IPoint;
            ImageResultLine imageResultLine = new ImageResultLine();
            if (pointFrom!=null && pointTo!=null)
            {
                double row1, column1, row2, column2;
                bool bResultPointFrom, bResultPointTo;
                bResultPointFrom =pointFrom.GetPoint(out column1, out row1, iIndex);
                bResultPointTo = pointTo.GetPoint(out column2, out row2, iIndex);
                if (bResultPointFrom && bResultPointTo)
                {
                    double dDisResult = HMisc.DistancePp(row1, column1, row2, column2);
                    imageResultLine.ResultA = MakeAngleToAngle180(row1, column1, row2, column2);
                    imageResultLine.ResultX = (column1 + column2) / 2.0;
                    imageResultLine.ResultY = (row1 + row2) / 2.0;
                    imageResultLine.ResultScore = 1;
                    imageResultLine.LineStartX = column1;
                    imageResultLine.LineStartY = row1;
                    imageResultLine.LineEndX = column2;
                    imageResultLine.LineEndY = row2;
                    imageResultLine.Result = true;
                    if (imageTool.Setting.ShowResultLine)
                    {
                        disWnd.DispArrow(row1, column1, row2, column2, "blue");

                    }
                    if (imageTool.Setting.ShowResultPoint)
                    {
                        HalconDotNet.HXLDCont crossXLDTemp = new HalconDotNet.HXLDCont();
                        crossXLDTemp.GenCrossContourXld(imageResultLine.ResultY, imageResultLine.ResultX, 20, 0);
                        disWnd.DispObj(crossXLDTemp, "green");
                    }

                }
                else
                {
                    
                }
                imageTool.ImageToolResults.Add(imageResultLine);

            }
        }
        private double MakeAngleToAngle180(double row1, double column1, double row2, double column2)
        {
            double dAngle = 0;
            if (Math.Abs((column2 - column1)) < 0.000001)
            {
                if ((row1 - row2) > 0)
                    dAngle = 90.0;
                else
                    dAngle = 270.0;

            }
            else
            {
                dAngle = Math.Atan2((row1 - row2), (column2 - column1));
                dAngle = HuToAngle(dAngle);
            }
            //让角度变成+/-180度
            double dAngleTemp = dAngle;
            int iAngleTemp = (int)(dAngleTemp * 1000.0);
            iAngleTemp = iAngleTemp % 360000;
            dAngleTemp = (double)iAngleTemp / 1000.0;
            if (dAngleTemp > 180)
            {
                dAngle = dAngleTemp - 360.0;
            }
            else
            {
                if (dAngleTemp < -180)
                {
                    dAngle = dAngleTemp + 360.0;
                }
                else
                {
                    dAngle = dAngleTemp;
                }
            }
            return dAngle;
        }

        public void RunPointToLine(HImage image, SmartDisplayControl.SmartDisplayControl disWnd, int iIndex, ImageToolBase toolFrom, ImageToolBase toolTo)
        {
            IPoint pointFrom = toolFrom as IPoint;
            ILineTool pointTo = toolTo as ILineTool;
            ImageResultLine imageResultLine = new ImageResultLine();
            if (pointFrom != null && pointTo != null)
            {
                double rowPoint, columnPoint,row1, column1, row2, column2, projectionRow, projectionColumn;

                bool bResultPointFrom, bResultPointTo;
                bResultPointFrom = pointFrom.GetPoint(out columnPoint, out rowPoint, iIndex);
                bResultPointTo = pointTo.GetLine(out row1, out column1, out row2, out column2, iIndex);
                if (bResultPointFrom && bResultPointTo)
                {
                    double dDisResult = HMisc.DistancePl(rowPoint, columnPoint, row1, column1, row2, column2);
                    HRegion regionLine = new HRegion();
                    HMisc.ProjectionPl(rowPoint, columnPoint, row1, column1, row2, column2, out projectionRow, out projectionColumn);
                    
                    imageResultLine.ResultA = MakeAngleToAngle180(rowPoint, columnPoint, projectionRow,projectionColumn);
                    imageResultLine.ResultX = (columnPoint + projectionColumn) / 2.0;
                    imageResultLine.ResultY = (rowPoint + projectionRow) / 2.0;
                    imageResultLine.ResultScore = 1;
                    imageResultLine.LineStartX = columnPoint;
                    imageResultLine.LineStartY = rowPoint;
                    imageResultLine.LineEndX = projectionColumn;
                    imageResultLine.LineEndY = projectionRow;
                    imageResultLine.Result = true;
                    if (imageTool.Setting.ShowResultLine)
                    {
                        disWnd.DispArrow(rowPoint, columnPoint, projectionRow, projectionColumn, "blue");

                    }
                    if (imageTool.Setting.ShowResultPoint)
                    {
                        HalconDotNet.HXLDCont crossXLDTemp = new HalconDotNet.HXLDCont();
                        crossXLDTemp.GenCrossContourXld(imageResultLine.ResultY, imageResultLine.ResultX, 20, 0);
                        disWnd.DispObj(crossXLDTemp, "green");
                    }

                }
                else
                {

                }
                imageTool.ImageToolResults.Add(imageResultLine);

            }
        }
        public void RunLineToLine(HImage image, SmartDisplayControl.SmartDisplayControl disWnd, int iIndex, ImageToolBase toolFrom, ImageToolBase toolTo)
        {
            ILineTool pointFrom = toolFrom as ILineTool;
            ILineTool pointTo = toolTo as ILineTool;
            ImageResultLine imageResultLine = new ImageResultLine();
            if (pointFrom != null && pointTo != null)
            {
                HTuple row, column, overlay;
                double row1_1, column1_1, row1_2, column1_2, row2_1, column2_1, row2_2, column2_2;

                bool bResultPointFrom, bResultPointTo;
                bResultPointFrom = pointFrom.GetLine(out row1_1, out column1_1, out  row1_2, out column1_2, iIndex);
                bResultPointTo = pointTo.GetLine(out row2_1, out column2_1, out row2_2, out column2_2, iIndex);
                if (bResultPointFrom && bResultPointTo)
                {
                    
                    HRegion regionLine = new HRegion();
                    HOperatorSet.IntersectionLines(row1_1, column1_1, row1_2, column1_2,
                           row2_1, column2_1, row2_2, column2_2,
                           out row, out column, out overlay);
                    HTuple hTupleRow, hTupleCol;
                    HOperatorSet.IntersectionLineCircle(row2_1, column2_1, row2_2, column2_2, row, column, 50, 0, Math.PI * 2.0, "positive", out hTupleRow, out hTupleCol);
                    imageResultLine.ResultA = MakeAngleToAngle180(row2_1, column2_1, row2_2, column2_2);
                    imageResultLine.ResultX = column;
                    imageResultLine.ResultY = row;
                    imageResultLine.ResultScore = 1;
                    imageResultLine.LineStartX = column2_1;
                    imageResultLine.LineStartY = row2_1;
                    imageResultLine.LineEndX = column2_2;
                    imageResultLine.LineEndY = row2_2;
                    imageResultLine.Result = true;
                    if (imageTool.Setting.ShowResultLine)
                    {
                        disWnd.DispArrow(imageResultLine.LineStartY, imageResultLine.LineStartX, imageResultLine.LineEndY, imageResultLine.LineEndX, "blue");

                    }
                    if (imageTool.Setting.ShowResultPoint)
                    {
                        HalconDotNet.HXLDCont crossXLDTemp = new HalconDotNet.HXLDCont();
                        crossXLDTemp.GenCrossContourXld(imageResultLine.ResultY, imageResultLine.ResultX, 20, 0);
                        disWnd.DispObj(crossXLDTemp, "green");
                    }

                }
                else
                {

                }
                imageTool.ImageToolResults.Add(imageResultLine);

            }
        }
        public void RunCircleToLine(HImage image, SmartDisplayControl.SmartDisplayControl disWnd, int iIndex, ImageToolBase toolFrom, ImageToolBase toolTo)
        {
            ICircleTool pointFrom = toolFrom as ICircleTool;
            ILineTool pointTo = toolTo as ILineTool;
            ImageResultLine imageResultLine = new ImageResultLine();
            if (pointFrom != null && pointTo != null)
            {
                double row, column,dRaduis;
                double row1, column1, row2, column2;

                bool bResultPointFrom, bResultPointTo;
                bResultPointFrom = pointFrom.GetCircle(out column, out row, out dRaduis, iIndex);
                bResultPointTo = pointTo.GetLine(out row1, out column1, out row2, out column2, iIndex);
                if (bResultPointFrom && bResultPointTo)
                {

                    HRegion regionLine = new HRegion();
                   
                    HTuple hTupleRow, hTupleCol;
                    imageResultLine.ResultA = MakeAngleToAngle180(row1, column1, row2, column2);
                    HOperatorSet.IntersectionLineCircle(row1, column1, row2, column2, row, column, dRaduis, 0, Math.PI * 2.0, "positive", out hTupleRow, out hTupleCol);
                    
                    imageResultLine.ResultX = hTupleCol.DArr[(int)imageTool.Setting.PointIndex];
                    imageResultLine.ResultY = hTupleRow.DArr[(int)imageTool.Setting.PointIndex];


                    HOperatorSet.IntersectionLineCircle(row1, column1, row2, column2, imageResultLine.ResultY, imageResultLine.ResultX, dRaduis, 0, Math.PI * 2.0, "positive", out hTupleRow, out hTupleCol);

                    imageResultLine.ResultScore = 1;
                    imageResultLine.LineStartX = column1;
                    imageResultLine.LineStartY = row1;
                    imageResultLine.LineEndX = column2;
                    imageResultLine.LineEndY = row2;
                    imageResultLine.Result = true;
                    if (imageTool.Setting.ShowResultLine)
                    {
                        disWnd.DispArrow(imageResultLine.LineStartY, imageResultLine.LineStartX, imageResultLine.LineEndY, imageResultLine.LineEndX, "blue");

                    }
                    if (imageTool.Setting.ShowResultPoint)
                    {
                        HalconDotNet.HXLDCont crossXLDTemp = new HalconDotNet.HXLDCont();
                        crossXLDTemp.GenCrossContourXld(imageResultLine.ResultY, imageResultLine.ResultX, 20, 0);
                        disWnd.DispObj(crossXLDTemp, "green");
                    }

                }
                else
                {

                }
                imageTool.ImageToolResults.Add(imageResultLine);

            }
        }
        private double HuToAngle(double dHu)
        {
            return dHu / Math.PI * 180.0;
        }
        private double AngleToHu(double dAngle)
        {
            return dAngle / 180.0 * Math.PI;
        }
    }
}
